﻿namespace Foundation.Core
{
    public interface ISelectParameterValueProvider
    {
        ISelectParameterValue GetValue(IDictionary<string, object> arguments, SelectItemLoadMethodParameter parameter);
    }

    public interface ISelectParameterAsyncValueProvider : ISelectParameterValueProvider
    {
        /// <summary>
        /// 取值
        /// </summary>
        /// <param name="arguments"></param>
        /// <returns></returns>
        Task<ISelectParameterValue> GetValueAsync(IDictionary<string, object> arguments, SelectItemLoadMethodParameter parameter, CancellationToken cancellationToken = default);
    }

    public interface ISelectParameterValue
    {
        /// <summary>
        /// 是否成功
        /// </summary>
        public bool Success { get; }

        /// <summary>
        /// 参数值
        /// </summary>
        object Value { get; }

        /// <summary>
        /// 格式的参数值
        /// </summary>
        string FormattedValue { get; }
    }

    /// <summary>
    /// 参数值
    /// </summary>
    public class SelectParameterValue : ISelectParameterValue
    {
        string _formattedValue;
        bool _hasFormatted;

        Func<object, string> _formatter;

        public SelectParameterValue()
        {
        }

        public SelectParameterValue(bool success, object value, Func<object, string> formatter)
        {
            Success = success;
            Value = value;
            _formatter = formatter;
        }

        public SelectParameterValue(bool success, object value, string formattedValue)
        {
            Success = success;
            Value = value;
            _formattedValue = formattedValue;
            _hasFormatted = formattedValue != null;
        }

        public bool Success { get; }

        public object Value { get; }

        public virtual string FormattedValue => GetFormattedValue();

        public void SetFormatter(Func<object, string> formatter)
        {
            if (formatter == null) return;

            _formatter = formatter;
            _formattedValue = null;
            _hasFormatted = false;
        }

        public string GetFormattedValue()
        {
            if (Success && !_hasFormatted)
            {
                _formattedValue = _formatter?.Invoke(this.Value);
                _hasFormatted = true;
            }

            return _formattedValue;
        }
    }
}
